home *** CD-ROM | disk | FTP | other *** search
- (*===========================================================================*)
- (* Used to send/control data frames to TNC *)
- (* *)
- (* Copyright 1988, 1989, 1990, 1991 by H. Roy Engehausen. All rights *)
- (* reserved. *)
- (* *)
- (*===========================================================================*)
-
- {$UNDEF DEBUG}
- {$UNDEF TRACE}
- {$UNDEF WRITE}
- {$UNDEF DEBUG2} (* Used to debug receive frame pending *)
- {$UNDEF DEBUG3} (* Used to debug receive frame pending *)
-
- UNIT BBSDATA;
-
- INTERFACE
-
- USES
- bbdummy;
-
- PROCEDURE send_tnc_data_str(in_str : STRING);
- PROCEDURE send_tnc_data (in_long : str_mixed_ptr);
- PROCEDURE send_tnc_data_ub (from_here : POINTER; length_to_send : WORD);
- FUNCTION send_unacked(ignore_r_pending : BOOLEAN) : BYTE;
- FUNCTION send_pending(ignore_r_pending : BOOLEAN) : BYTE;
- PROCEDURE send_flush;
- PROCEDURE send_drain;
-
- IMPLEMENTATION
-
- USES
- CRT,
- DOS,
- bblc,
- bblstr,
- bbmisc4,
- bbmore,
- bbsess,
- bbsrt,
- bbstack,
- bbstr,
- bbtask,
- bbtrace,
- bbwin;
-
- {$I BBMACRO.PAS}
-
- (*===========================================================================*)
- (* Forwards *)
- (*===========================================================================*)
-
- PROCEDURE put_a_packet; FORWARD;
- PROCEDURE put_data_error; FORWARD;
-
- (*===========================================================================*)
- (* Add linefeeds *)
- (*===========================================================================*)
-
- PROCEDURE add_lf;
-
- VAR
- i : WORD;
- l : WORD;
-
- BEGIN;
-
- (*-----------------------------------------------------------------------*)
- (* Only do this on telephones and not binary *)
- (*-----------------------------------------------------------------------*)
-
- IF (active_port^.port_type <> port_modem)
- OR NOT active_port^.modem_crlf
- OR active_tcb^.tcb_binary THEN
- EXIT;
-
- (*-----------------------------------------------------------------------*)
- (* Get ready for loop *)
- (*-----------------------------------------------------------------------*)
-
- i := 0;
- l := active_tcb^.o_data.long_length;
-
- {$IFDEF DEBUG}
- WRITELN('1) i = ', i, ' -- l = ', l);
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Loop adding linefeeds *)
- (*-----------------------------------------------------------------------*)
-
- WHILE (i < l) AND (l < SIZEOF(active_tcb^.o_data.long_data)) DO
- BEGIN;
-
- INC(i);
-
- (*-------------------------------------------------------------------*)
- (* CR without LF *)
- (*-------------------------------------------------------------------*)
-
- IF (active_tcb^.o_data.long_data[i] = cr)
- AND ((i = l) OR (active_tcb^.o_data.long_data[i+1] <> lf)) THEN
- BEGIN;
-
- {$IFDEF DEBUG}
- WRITELN('2) i = ', i, ' -- l = ', l);
- {$ENDIF}
-
- (*---------------------------------------------------------------*)
- (* Shift everything right *)
- (*---------------------------------------------------------------*)
-
- MOVE(active_tcb^.o_data.long_data[i+1],
- active_tcb^.o_data.long_data[i+2],
- l-i);
-
- (*---------------------------------------------------------------*)
- (* Add linefeed *)
- (*---------------------------------------------------------------*)
-
- active_tcb^.o_data.long_data[i+1] := lf;
-
- (*---------------------------------------------------------------*)
- (* Bump counters *)
- (*---------------------------------------------------------------*)
-
- INC(l);
- INC(i);
-
- {$IFDEF DEBUG}
- stack_depth;
- {$ENDIF}
-
- END; (*----- End of adding a LF -----------------------------------*)
-
- END; (*----- End loop thru the packet ---------------------------------*)
-
- (*-----------------------------------------------------------------------*)
- (* Set new length *)
- (*-----------------------------------------------------------------------*)
-
- active_tcb^.o_data.long_length := l;
- IF l > 255 THEN
- l := 255;
- active_tcb^.o_data.str_data[0] := CHR(l);
-
- {$IFDEF DEBUG}
- WRITELN('3) i = ', i, ' -- l = ', l);
- {$ENDIF}
-
- END; (*----- End of add_lf ------------------------------------------------*)
-
- (*===========================================================================*)
- (* Unblocked data send *)
- (*===========================================================================*)
-
- PROCEDURE send_tnc_data_ub (from_here : POINTER; length_to_send : WORD);
-
- TYPE
- array_overlay = ARRAY[0..10000] OF BYTE;
-
- VAR
- data_place : ^array_overlay;
- current_length : WORD;
- length_to_move : WORD;
- this_max_pac : WORD;
-
- BEGIN;
-
- data_place := from_here;
-
- (*-----------------------------------------------------------------------*)
- (* Get maximum packet size *)
- (*-----------------------------------------------------------------------*)
-
- this_max_pac := active_tcb^.max_pac;
-
- (*-----------------------------------------------------------------------*)
- (* If buffer is full then flush *)
- (*-----------------------------------------------------------------------*)
-
- IF active_tcb^.o_data.long_length >= this_max_pac THEN
- send_flush;
-
- (*-----------------------------------------------------------------------*)
- (* Get current length in buffer *)
- (*-----------------------------------------------------------------------*)
-
- current_length := active_tcb^.o_data.long_length;
-
- (*-----------------------------------------------------------------------*)
- (* Loop until nothing left to send *)
- (*-----------------------------------------------------------------------*)
-
- WHILE length_to_send > 0 DO
- BEGIN;
-
- (*-------------------------------------------------------------------*)
- (* Calculate space in buffer *)
- (*-------------------------------------------------------------------*)
-
- length_to_move := this_max_pac - current_length;
-
- (*-------------------------------------------------------------------*)
- (* If we have less data than space, just move data *)
- (*-------------------------------------------------------------------*)
-
- IF length_to_send < length_to_move THEN
- length_to_move := length_to_send;
-
- (*-------------------------------------------------------------------*)
- (* Move data *)
- (*-------------------------------------------------------------------*)
-
- MOVE(data_place^,
- active_tcb^.o_data.long_data[current_length + 1],
- length_to_move);
-
- (*-------------------------------------------------------------------*)
- (* Bump counters appropriately *)
- (*-------------------------------------------------------------------*)
-
- INC(current_length, length_to_move);
- DEC(length_to_send, length_to_move);
-
- (*-------------------------------------------------------------------*)
- (* Fill in lengths *)
- (*-------------------------------------------------------------------*)
-
- active_tcb^.o_data.long_length := current_length;
-
- active_tcb^.o_data.str_data[0] := CHR(min_w(255, current_length));
-
- (*-------------------------------------------------------------------*)
- (* Write the packet *)
- (*-------------------------------------------------------------------*)
-
- put_a_packet;
-
- (*-------------------------------------------------------------------*)
- (* Nothing left in buffer *)
- (*-------------------------------------------------------------------*)
-
- current_length := 0;
-
- (*-------------------------------------------------------------------*)
- (* Adjust data pointer *)
- (*-------------------------------------------------------------------*)
-
- data_place := @data_place^[length_to_move];
-
- END; (*----- Loop sending data ----------------------------------------*)
-
- END;
-
- (*===========================================================================*)
- (* Long data send *)
- (*===========================================================================*)
-
- PROCEDURE send_tnc_data(in_long : str_mixed_ptr);
-
- VAR
- this_max_pac : WORD;
- this_o_data : str_mixed_ptr;
-
- BEGIN;
-
- this_max_pac := active_tcb^.max_pac;
- IF this_max_pac = 0 THEN
- this_max_pac := 255;
-
-
- IF active_tcb^.o_data.long_length + in_long^.long_length
- > this_max_pac THEN
- BEGIN;
-
- put_a_packet;
-
- l_cat_size(@active_tcb^.o_data, in_long, this_max_pac);
-
- IF in_long^.long_length <> 0 THEN
- BEGIN;
- put_a_packet;
- active_tcb^.o_data := in_long^;
- END;
-
- END
- ELSE
- l_cat_size(@active_tcb^.o_data, in_long, this_max_pac);
-
- END;
-
- (*===========================================================================*)
- (* String data send *)
- (*===========================================================================*)
-
- PROCEDURE send_tnc_data_str(in_str : STRING);
-
- {$UNDEF DEBUG}
-
- VAR
- i : WORD;
- this_max_pac : WORD;
- this_o_data : str_mixed_ptr;
-
- BEGIN;
-
- (*-----------------------------------------------------------------------*)
- (* Increment more *)
- (*-----------------------------------------------------------------------*)
-
- more_add_str(in_str);
-
- (*-----------------------------------------------------------------------*)
- (* Get the current max pac and buffer *)
- (*-----------------------------------------------------------------------*)
-
- this_max_pac := active_tcb^.max_pac;
- this_o_data := @active_tcb^.o_data;
-
- (*-----------------------------------------------------------------------*)
- (* A little debugging please *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
- stack_push('');
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Find out if there is a carriage return in the data already processed *)
- (*-----------------------------------------------------------------------*)
-
- i := l_pos(@active_tcb^.o_data, cr);
- IF i > 255 THEN
- i := 0;
-
- (*-----------------------------------------------------------------------*)
- (* A little debugging please *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
- stack_test('SDATA1');
-
- {$IFDEF TRACE}
- trace_data('1T', active_tcb^.o_data.long_length, NIL,
- active_tcb^.o_data.str_data);
- trace_data('1I', LENGTH(in_str), NIL, in_str);
- {$ENDIF}
-
- {$IFDEF WRITE}
- WRITELN('1T ', active_tcb^.o_data.long_length, ' -- ',
- active_tcb^.o_data.str_data);
- WRITELN('1I ', LENGTH(in_str), ' -- ', in_str);
- {$ENDIF}
-
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* See if we will exceed maximum packet size *)
- (*-----------------------------------------------------------------------*)
-
- IF (this_o_data^.long_length + LENGTH(in_str)) > this_max_pac THEN
- BEGIN;
-
- (*-------------------------------------------------------------------*)
- (* Maximum packet size to be exceeded! *)
- (*-------------------------------------------------------------------*)
-
- (*-------------------------------------------------------------------*)
- (* A little debugging please *)
- (*-------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
-
- {$IFDEF TRACE}
- trace_data('2T', this_o_data^.long_length, NIL,
- this_o_data^.str_data);
- trace_data('2I', LENGTH(in_str), NIL, in_str);
- {$ENDIF}
-
- {$IFDEF WRITE}
- WRITELN('2T ', this_o_data^.long_length, ' -- ',
- this_o_data^.str_data);
- WRITELN('2I ', LENGTH(in_str), ' -- ', in_str);
- {$ENDIF}
-
- {$ENDIF}
-
- (*-------------------------------------------------------------------*)
- (* Maximum packet size to be exceeded! If transparent mode or if *)
- (* we don't have a CR yet, fill out the buffer. *)
- (*-------------------------------------------------------------------*)
-
- IF ((active_tcb^.uid_data.user_flag AND user_f_trans) <> 0)
- OR (i = 0) THEN
- l_cat_str_size(this_o_data, in_str, this_max_pac);
-
- (*-------------------------------------------------------------------*)
- (* A little debugging please *)
- (*-------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
-
- stack_test('SDATA3');
-
- {$IFDEF TRACE}
- trace_data('3T', this_o_data^.long_length, NIL,
- this_o_data^.str_data);
- trace_data('3I', LENGTH(in_str), NIL, in_str);
- {$ENDIF}
-
- {$IFDEF WRITE}
- WRITELN('3T ', this_o_data^.long_length, ' -- ',
- this_o_data^.str_data);
- WRITELN('3I ', LENGTH(in_str), ' -- ', in_str);
- {$ENDIF}
-
- {$ENDIF}
-
- (*-------------------------------------------------------------------*)
- (* Take the packet we just built and write it out *)
- (*-------------------------------------------------------------------*)
-
- put_a_packet;
-
- (*-------------------------------------------------------------------*)
- (* A little debugging please *)
- (*-------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
-
- stack_test('SDATA4'); (*STACK TEST*)
-
- {$IFDEF TRACE}
- trace_data('4T', this_o_data^.long_length, NIL,
- this_o_data^.str_data);
- trace_data('4I', LENGTH(in_str), NIL, in_str);
- {$ENDIF}
-
- {$IFDEF WRITE}
- WRITELN('4T ', this_o_data^.long_length, ' -- ',
- this_o_data^.str_data);
- WRITELN('4I ', LENGTH(in_str), ' -- ', in_str);
- {$ENDIF}
-
- {$ENDIF}
-
- (*-------------------------------------------------------------------*)
- (* Stick the next bunch of data into the packet *)
- (*-------------------------------------------------------------------*)
-
- l_cat_str_size(this_o_data, in_str, this_max_pac);
-
- (*-------------------------------------------------------------------*)
- (* A little debugging please *)
- (*-------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
-
- stack_test('SDATA5');
-
- {$IFDEF TRACE}
- trace_data('5T', this_o_data^.long_length, NIL,
- this_o_data^.str_data);
- trace_data('5I', LENGTH(in_str), NIL, in_str);
- {$ENDIF}
-
- {$IFDEF WRITE}
- WRITELN('5T ', this_o_data^.long_length, ' -- ',
- this_o_data^.str_data);
- WRITELN('5I ', LENGTH(in_str), ' -- ', in_str);
- {$ENDIF}
-
- {$ENDIF}
-
- (*-------------------------------------------------------------------*)
- (* If there is still data in the input string then loop *)
- (*-------------------------------------------------------------------*)
-
- WHILE LENGTH(in_str) > 0 DO
- BEGIN;
-
- (*---------------------------------------------------------------*)
- (* A little debugging please *)
- (*---------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
-
- {$IFDEF TRACE}
- trace_data('6T', this_o_data^.long_length, NIL,
- this_o_data^.str_data);
- trace_data('6I', LENGTH(in_str), NIL, in_str);
- {$ENDIF}
-
- {$IFDEF WRITE}
- WRITELN('6T ', this_o_data^.long_length, ' -- ',
- this_o_data^.str_data);
- WRITELN('6I ', LENGTH(in_str), ' -- ', in_str);
- {$ENDIF}
-
- {$ENDIF}
-
- (*---------------------------------------------------------------*)
- (* Send this packet *)
- (*---------------------------------------------------------------*)
-
- put_a_packet;
-
- (*---------------------------------------------------------------*)
- (* A little debugging please *)
- (*---------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
-
- stack_test('SDATA7'); (*STACK TEST*)
-
- {$IFDEF TRACE}
- trace_data('7T', this_o_data^.long_length, NIL,
- this_o_data^.str_data);
- trace_data('7I', LENGTH(in_str), NIL, in_str);
- {$ENDIF}
-
- {$IFDEF WRITE}
- WRITELN('7T ', this_o_data^.long_length, ' -- ',
- this_o_data^.str_data);
- WRITELN('7I ', LENGTH(in_str), ' -- ', in_str);
- {$ENDIF}
-
- {$ENDIF}
-
- (*---------------------------------------------------------------*)
- (* Build the next packet *)
- (*---------------------------------------------------------------*)
-
- l_cat_str_size(this_o_data, in_str, this_max_pac);
-
- (*---------------------------------------------------------------*)
- (* A little debugging please *)
- (*---------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
-
- stack_test('SDATA8');
-
- {$IFDEF TRACE}
- trace_data('8T', this_o_data^.long_length, NIL,
- this_o_data^.str_data);
- trace_data('8I', LENGTH(in_str), NIL, in_str);
- {$ENDIF}
-
- {$IFDEF WRITE}
- WRITELN('8T ', this_o_data^.long_length, ' -- ',
- this_o_data^.str_data);
- WRITELN('8I ', LENGTH(in_str), ' -- ', in_str);
- {$ENDIF}
-
- {$ENDIF}
-
- END; (*----- End loop sending packets until input stream is done --*)
-
- END
- ELSE
-
- (*---------------------------------------------------------------------*)
- (* Maximum packet size won't be exceeded so just glue things together *)
- (*---------------------------------------------------------------------*)
-
- l_cat_str_size(this_o_data, in_str, this_max_pac);
-
- (*-----------------------------------------------------------------------*)
- (* A little debugging please *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
-
- stack_test('SDATA9');
-
- {$IFDEF TRACE}
- trace_data('9T', this_o_data^.long_length, NIL, this_o_data^.str_data);
- trace_data('9I', LENGTH(in_str), NIL, in_str);
- {$ENDIF}
-
- {$IFDEF WRITE}
- WRITELN('9T ', this_o_data^.long_length, ' -- ', this_o_data^.str_data);
- WRITELN('9I ', LENGTH(in_str), ' -- ', in_str);
- {$ENDIF}
-
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Add line feeds as needed *)
- (*-----------------------------------------------------------------------*)
-
- add_lf;
-
- (*-----------------------------------------------------------------------*)
- (* A little debugging please *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
-
- stack_pop ('SDATAA');
-
- {$IFDEF TRACE}
- trace_data('AT', this_o_data^.long_length, NIL, this_o_data^.str_data);
- trace_data('AI', LENGTH(in_str), NIL, in_str);
- {$ENDIF}
-
- {$IFDEF WRITE}
- WRITELN('AT ', this_o_data^.long_length, ' -- ', this_o_data^.str_data);
- WRITELN('AI ', LENGTH(in_str), ' -- ', in_str);
- {$ENDIF}
-
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* If resulting packet is too big then send it *)
- (*-----------------------------------------------------------------------*)
-
- IF this_o_data^.long_length > this_max_pac THEN
- put_a_packet;
-
- (*-----------------------------------------------------------------------*)
- (* If this is a console and a CR is present then send everything we have *)
- (*-----------------------------------------------------------------------*)
-
- IF active_tcb^.tcb_console AND (l_pos(this_o_data, cr) <> 0) THEN
- send_flush;
-
- (*-----------------------------------------------------------------------*)
- (* A little debugging please *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
-
- stack_pop ('SDATAB'); (*STACK TEST*)
-
- {$IFDEF TRACE}
- trace_data('BT', this_o_data^.long_length, NIL, this_o_data^.str_data);
- trace_data('BI', LENGTH(in_str), NIL, in_str);
- {$ENDIF}
-
- {$IFDEF WRITE}
- WRITELN('BT ', this_o_data^.long_length, ' -- ', this_o_data^.str_data);
- WRITELN('BI ', LENGTH(in_str), ' -- ', in_str);
- {$ENDIF}
-
- {$ENDIF}
-
- END;
-
- (*===========================================================================*)
- (* Flush the send buffers *)
- (*===========================================================================*)
-
- PROCEDURE send_flush;
-
- BEGIN;
-
- IF active_tcb^.o_data.long_length <> 0 THEN
- put_a_packet;
-
- END;
-
- (*===========================================================================*)
- (* Flush the send buffers and wait for all the ACKS. *)
- (*===========================================================================*)
-
- PROCEDURE send_drain;
-
- BEGIN;
-
- send_flush;
-
- WHILE send_unacked(TRUE) > 0 DO
- task_switch;
-
- END;
-
- (*===========================================================================*)
- (* Get number of packets in the queue but not transmitted at all *)
- (*===========================================================================*)
-
- FUNCTION send_pending(ignore_r_pending : BOOLEAN) : BYTE;
-
- CONST
- l_command : STRING[1] = 'L';
-
- VAR
- i : WORD;
- l_pending : BYTE;
- r_pending : BYTE;
- word_cnt : BYTE;
- work_str : STRING;
-
- LABEL
- bad_response_handler;
-
- BEGIN;
-
- (*-----------------------------------------------------------------------*)
- (* If we are talking to the console, nothing can be pending *)
- (*-----------------------------------------------------------------------*)
-
- IF active_tcb^.tcb_console THEN
- BEGIN;
- task_switch;
- send_pending := 0;
- EXIT;
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Loop around checking the link state until things are quiet *)
- (*-----------------------------------------------------------------------*)
-
- REPEAT
-
- (*---------------------------------------------------------------------*)
- (* Send L command *)
- (*---------------------------------------------------------------------*)
-
- bad_response_handler:
-
- cmd_tnc(@l_command, FALSE);
-
- (*---------------------------------------------------------------------*)
- (* *)
- (* L response *)
- (* Word 1 -- Number of link status messages waiting *)
- (* Word 2 -- Number of data packets waiting *)
- (* Word 3 -- Number of packets awaiting 1st transmission *)
- (* Word 4 -- Number of frames send at least once *)
- (* Word 5 -- Number of retries *)
- (* Word 6 -- Link status # *)
- (* *)
- (*---------------------------------------------------------------------*)
-
- WITH active_tcb^ DO
- IF (tnc_type <> t_to_h_okmsg) OR (tnc_data.long_length < 3) THEN
- BEGIN;
- window_write_critical_i(
- 'SDATA -- Improper response to L command on '
- + port_chan_s + ' -- Type was ',
- tnc_type);
- window_write_critical('Answer -- ',
- tnc_data.str_data);
- DELAY(800);
- GOTO bad_response_handler;
- END;
-
- word_cnt := WORDS(active_tcb^.tnc_data.str_data);
-
- (*---------------------------------------------------------------------*)
- (* Check for link status messages pending *)
- (*---------------------------------------------------------------------*)
-
- IF word_cnt >= 1 THEN
- BEGIN;
- work_str := subword(@active_tcb^.tnc_data.str_data, 1, 1);
- work_str[1] := work_str[LENGTH(work_str)];
- IF work_str[1] >= '0' THEN
- l_pending := ORD(work_str[1]) - ORD('0')
- ELSE
- l_pending := 1;
-
- IF active_tcb^.tnc_in_chn <> NIL THEN
- l_pending := l_pending + pending_chain(4);
-
- IF l_pending > 0 THEN
- link_pending;
-
- END
- ELSE
- l_pending := 0;
-
- (*---------------------------------------------------------------------*)
- (* Check for data messages pending. If one is pending and we can *)
- (* complete the buffer, try to do so *)
- (*---------------------------------------------------------------------*)
-
- IF (NOT ignore_r_pending) AND (l_pending = 0) AND (word_cnt >= 2) THEN
- BEGIN;
-
- {$IFDEF DEBUG2}
- WRITELN('SPEND1L -- ', active_tcb^.tnc_data.str_data);
- {$ENDIF}
-
- (*-----------------------------------------------------------------*)
- (* Calculate number of pending packets *)
- (*-----------------------------------------------------------------*)
-
- work_str := subword(@active_tcb^.tnc_data.str_data, 2, 1);
- work_str[1] := work_str[LENGTH(work_str)];
-
- {$IFDEF DEBUG2}
- WRITELN('SPEND2L -- ', ORD(work_str[1]));
- {$ENDIF}
-
- IF work_str[1] >= '0' THEN
- r_pending := ORD(work_str[LENGTH(work_str)]) - ORD('0')
- ELSE
- r_pending := 1;
-
- IF LENGTH(work_str) > 1 THEN
- INC(r_pending, 10);
-
- {$IFDEF DEBUG2}
- WRITELN('SPEND3L -- ', r_pending);
- {$ENDIF}
-
- (*-----------------------------------------------------------------*)
- (* If data packets are in the queue, add them too.... *)
- (*-----------------------------------------------------------------*)
-
- IF active_tcb^.tnc_in_chn <> NIL THEN
- r_pending := r_pending + pending_chain(3);
-
- (*-----------------------------------------------------------------*)
- (* If we have some packets pending, better see what to do *)
- (*-----------------------------------------------------------------*)
-
- IF r_pending <> 0 THEN
- BEGIN;
-
- {$IFDEF DEBUG3}
- WRITELN('SPEND1P -- ', active_tcb^.tnc_data.str_data);
- WRITELN(' rpend -- ', r_pending);
- {$ENDIF}
-
- (*-------------------------------------------------------------*)
- (* Set I as a switch showing "complete" data is present *)
- (*-------------------------------------------------------------*)
-
- IF active_tcb^.tcb_binary THEN
- i := active_tcb^.i_data.long_length
- ELSE
- i := l_pos(@active_tcb^.i_data, cr);
-
- (*-------------------------------------------------------------*)
- (* If we don't have "complete" data, go see if we can fetch som*)
- (*-------------------------------------------------------------*)
-
- IF (i = 0) AND (active_tcb^.i_data.long_length < 255) THEN
- BEGIN;
-
- (*---------------------------------------------------------*)
- (* Poll for data only *)
- (*---------------------------------------------------------*)
-
- send_recv_tnc(3);
-
- {$IFDEF DEBUG2}
- WRITELN('SPEND2P -- ', active_tcb^.tnc_data.str_data);
- WRITELN(' type -- ', active_tcb^.tnc_type);
- {$ENDIF}
-
- (*---------------------------------------------------------*)
- (* See if data was appropriate *)
- (*---------------------------------------------------------*)
-
- IF (active_tcb^.tnc_type <> t_to_h_conn)
- AND (active_tcb^.channel <> 0) THEN
- BEGIN;
- window_write_critical_i(
- 'SPENDING Improper response to G command on '
- + active_tcb^.port_chan_s + ' -- Type was ',
- active_tcb^.tnc_type);
- window_write_critical('Answer -- ',
- active_tcb^.tnc_data.str_data);
- DELAY(800);
- END;
-
- (*---------------------------------------------------------*)
- (* Put data in the buffer *)
- (*---------------------------------------------------------*)
-
- l_cat(@active_tcb^.i_data, @active_tcb^.tnc_data);
-
- (*---------------------------------------------------------*)
- (* Force non-zero r_pending so we loop *)
- (*---------------------------------------------------------*)
-
- r_pending := 1;
-
- END
- ELSE
-
- (*-----------------------------------------------------------*)
- (* If we arrive here then we have "complete" data awaiting *)
- (* in the buffer. r_pending set to zero to force exit *)
- (*-----------------------------------------------------------*)
-
- r_pending := 0;
-
- END; (*----- End of IF (with ELSE) for "complete" data check ----*)
-
- END
- ELSE
-
- (*-------------------------------------------------------------------*)
- (* No data is pending, or we don't want to know about it *)
- (*-------------------------------------------------------------------*)
-
- r_pending := 0;
-
- (*---------------------------------------------------------------------*)
- (* If we processed incoming data or link status then loop *)
- (*---------------------------------------------------------------------*)
-
- UNTIL (l_pending + r_pending) = 0;
-
- (*-----------------------------------------------------------------------*)
- (* Get number of packets pending (but not sent yet) *)
- (*-----------------------------------------------------------------------*)
-
- send_pending := 0;
- IF word_cnt >= 3 THEN
- BEGIN;
- work_str := subword(@active_tcb^.tnc_data.str_data, 3, 1);
- l_pending := ORD(work_str[LENGTH(work_str)]);
- IF l_pending > ORD('0') THEN
- send_pending := l_pending - ORD('0');
- END;
-
- END;
-
- (*===========================================================================*)
- (* Get number of packets in the queue but not acked. *)
- (*===========================================================================*)
-
- FUNCTION send_unacked(ignore_r_pending : BOOLEAN) : BYTE;
-
- VAR
- i : BYTE;
- out_pend : BYTE;
- work_str : STRING[3];
-
- BEGIN;
-
- IF active_tcb^.tcb_console THEN
- BEGIN;
- task_switch;
- send_unacked := 0;
- EXIT;
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Get the number of packets in the queue but not transmitted. This *)
- (* function call also leaves the result of the "L" command in the buffer *)
- (*-----------------------------------------------------------------------*)
-
- out_pend := send_pending(ignore_r_pending);
-
- (*-----------------------------------------------------------------------*)
- (* Get the number of packets in the transmitted but unacked state *)
- (*-----------------------------------------------------------------------*)
-
- WITH active_tcb^ DO
- IF words(tnc_data.str_data) >= 4 THEN
- BEGIN;
- work_str := subword(@tnc_data.str_data, 4, 1);
- i := ORD(work_str[LENGTH(work_str)]);
- IF (i > ORD('0')) AND (out_pend < ORD('0')) THEN
- out_pend := out_pend + i - ORD('0');
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Got'em *)
- (*-----------------------------------------------------------------------*)
-
- send_unacked := out_pend;
-
- END;
-
- (*===========================================================================*)
- (* Put a packet *)
- (*===========================================================================*)
-
- PROCEDURE put_a_packet;
-
- VAR
- dl : WORD;
- prefix : STRING[4];
- x_timeout : LONGINT;
-
- {$UNDEF DEBUG}
-
- BEGIN;
-
- WITH active_tcb^ DO
- BEGIN;
-
- (*-------------------------------------------------------------------*)
- (* Some debugging please *)
- (*-------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
-
- dl := o_data.long_length;
-
- WRITELN('PUTA0 --', dl, '-', o_data.str_data);
-
- IF dl = 0 THEN
- DELAY(1000);
-
- {$ENDIF}
-
- (*-------------------------------------------------------------------*)
- (* Add linefeeds as needed *)
- (*-------------------------------------------------------------------*)
-
- add_lf;
-
- (*-------------------------------------------------------------------*)
- (* Some debugging please *)
- (*-------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
-
- dl := o_data.long_length;
-
- WRITELN('PUTA1 --', dl, '-', o_data.str_data);
-
- IF dl = 0 THEN
- DELAY(1000);
-
- {$ENDIF}
-
- (*-------------------------------------------------------------------*)
- (* Get the data length *)
- (*-------------------------------------------------------------------*)
-
- dl := o_data.long_length;
-
- (*-------------------------------------------------------------------*)
- (* Some debugging please *)
- (*-------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
-
- WRITELN('PUTAPACKET --', dl, '-', o_data.str_data);
-
- IF dl = 0 THEN
- DELAY(1000);
-
- {$ENDIF}
-
- (*-------------------------------------------------------------------*)
- (* If no data at this point, we leave *)
- (*-------------------------------------------------------------------*)
-
- IF dl = 0 THEN
- EXIT;
-
- (*-------------------------------------------------------------------*)
- (* Prepare the display prefix *)
- (*-------------------------------------------------------------------*)
-
- prefix := port_chan_s + '>:';
-
- (*-------------------------------------------------------------------*)
- (* Calculate the transmitter time out. Its BIG! *)
- (*-------------------------------------------------------------------*)
-
- x_timeout := current_day_time + active_port^.time_out
- + active_port^.time_out;
-
- (*-------------------------------------------------------------------*)
- (* If too many packets already outstanding then wait for it to clear *)
- (*-------------------------------------------------------------------*)
-
- WHILE (active_port^.port_pend - send_pending(TRUE)) <= 0 DO
- BEGIN;
-
- (*---------------------------------------------------------------*)
- (* Transmitter time out *)
- (*---------------------------------------------------------------*)
-
- IF current_day_time > x_timeout THEN
- BEGIN;
- prefix := port_chan_s + 'T:';
- window_write(prefix, 'Transmit time out');
- force_tcb(active_tcb);
- END;
-
- (*---------------------------------------------------------------*)
- (* Wait at bunch of switch periods before proceeding *)
- (*---------------------------------------------------------------*)
-
- FOR dl := 1 TO 40 DO
- task_switch;
-
- END;
-
- (*-------------------------------------------------------------------*)
- (* Some debugging please *)
- (*-------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
- WRITELN('ENDWAIT');
- {$ENDIF}
-
- (*-------------------------------------------------------------------*)
- (* Move the data into the output buffer *)
- (*-------------------------------------------------------------------*)
-
- tnc_data := o_data;
-
- (*-------------------------------------------------------------------*)
- (* Display if wanted *)
- (*-------------------------------------------------------------------*)
-
- IF NOT tcb_no_show_sdata THEN
- window_write(prefix, tnc_data.str_data);
-
- (*-------------------------------------------------------------------*)
- (* Some debugging please *)
- (*-------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
- WRITELN('PAP-WHICH');
- DELAY(500);
- {$ENDIF}
-
- (*-------------------------------------------------------------------*)
- (* If this is not a console or we are not killing the task *)
- (*-------------------------------------------------------------------*)
-
- IF NOT (tcb_console OR tcb_dead_in_progress) THEN
- BEGIN;
-
- (*---------------------------------------------------------------*)
- (* Some debugging please *)
- (*---------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
- WRITELN('PAP-SRT');
- DELAY(500);
- {$ENDIF}
-
- (*---------------------------------------------------------------*)
- (* Send the data and check the response *)
- (*---------------------------------------------------------------*)
-
- send_recv_tnc(info_cmd_info);
- IF tnc_type <> t_to_h_ok THEN
- put_data_error;
-
- END
- ELSE
- REPEAT
-
- (*---------------------------------------------------------------*)
- (* Console or task is to die. If we are killing the task *)
- (* then this loop will never end *)
- (*---------------------------------------------------------------*)
-
- (*---------------------------------------------------------------*)
- (* Some debugging please *)
- (*---------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
- WRITELN('PAP-DEAD LOOP');
- {$ENDIF}
-
- (*---------------------------------------------------------------*)
- (* Switch tasks and get pending send info *)
- (*---------------------------------------------------------------*)
-
- task_switch;
- dl := send_pending(TRUE);
-
- UNTIL NOT tcb_dead_in_progress;
-
- (*-------------------------------------------------------------------*)
- (* Switch tasks to let someone else get a shot *)
- (*-------------------------------------------------------------------*)
-
- task_switch;
-
- (*-------------------------------------------------------------------*)
- (* Clear buffer *)
- (*-------------------------------------------------------------------*)
-
- o_data.long_length := 0;
- o_data.str_data := '';
-
- END;
-
- END;
-
- (*===========================================================================*)
- (* Non blank answer received when putting data to the TNC *)
- (*===========================================================================*)
-
- PROCEDURE put_data_error;
-
- BEGIN;
- window_write_critical(active_tcb^.port_chan_s
- + 'Non null response to data transmission',
- active_tcb^.tnc_data.str_data);
- END;
-
- END.